home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / vollvers / adamaslg / ovl.src / panel.c < prev    next >
C/C++ Source or Header  |  1998-12-18  |  7KB  |  302 lines

  1. /*
  2.     Visual panel handler functions, including the redraw of the
  3.     object area and clicking the play/stop button.
  4. */    
  5.  
  6. #include "extern.h"
  7. #include <stddef.h>
  8. #include <time.h>
  9. #include <vdi.h>
  10.  
  11. int vdi_handle, colours, tx_width, tx_height;
  12.  
  13. #define min(a,b) ((a < b) ? a : b)
  14. #define max(a,b) ((a > b) ? a : b)
  15.  
  16. /* 
  17.    Open virtual workstation for panel redraw.
  18.    The panel handler creates it's own virtual
  19.    workstation to have it's own attributes for
  20.    filling and text output.
  21.    
  22.    This function will be executed only once, after
  23.    loading the overlay.
  24. */
  25. void open_panelvwk(void)
  26. {
  27. int work_in[10], work_out[57], extent[8], d;
  28. int i;
  29. int dummy, t_attr[10];
  30.  
  31. vdi_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
  32.  
  33. for(i = 0; i < 10; work_in[i++] = 1);
  34. work_in[10] = 2;
  35.  
  36. v_opnvwk(work_in, &vdi_handle, work_out);
  37. vqt_attributes(vdi_handle, t_attr);
  38.  
  39. vst_alignment(vdi_handle, 0, 5, &dummy, &dummy);
  40. vst_height(vdi_handle, 6, &d, &d, &d, &d);
  41.  
  42. vqt_extent(vdi_handle, "W", extent);
  43. tx_width = extent[2] - extent[0]; 
  44. if (tx_width < 0) tx_width = -tx_width;
  45. tx_height = extent[1] - extent[7]; 
  46. if (tx_height < 0) tx_height = -tx_height;
  47.  
  48. vq_extnd(vdi_handle, FALSE, work_out);
  49. colours = work_out[13];
  50. }
  51.  
  52. /* 
  53.     Close the special panel virtual
  54.     workstation.
  55.  
  56.   This function will be executed only once, before
  57.   releasing the overlay from memory.
  58. */
  59. void close_panelvwk(void)
  60. {
  61. v_clsvwk(vdi_handle);
  62. }
  63.  
  64. /* 
  65.    Calculate rectangle intersection
  66. */
  67. int rc_intersect(int x1, int y1, int w1, int h1, 
  68.                                  int x2, int y2, int w2, int h2, 
  69.                                  int *xy)
  70. {
  71. int tx, ty, tw, th;
  72.  
  73. tw = min(x2 + w2, x1 + w1);
  74. th = min(y2 + h2, y1 + h1);
  75. tx = xy[0] = max(x2, x1);
  76. ty = xy[1] = max(y2, y1);
  77. xy[2] = tw - tx;
  78. xy[3] = th - ty;
  79.  
  80. return ((tw > tx) && (th > ty));
  81. }
  82.  
  83. /* 
  84.    Draw one of the panel buttons.
  85.    
  86.    x            -> Button x - position
  87.    y          -> Button y - position
  88.    w           -> Button width
  89.    h          -> Button height
  90.    button    -> Button number, used to draw the correct symbol
  91.    pressed-> Is the button currently selected?
  92.    
  93. */
  94. void draw_button(int x, int y, int w, int h, int button, int pressed)
  95. {
  96. int xy[10];
  97. int xc, yc;
  98.  
  99. if (colours >= 16)
  100.     vsf_color(vdi_handle, pressed ? 9 : 8);
  101. else
  102.     vsf_color(vdi_handle, pressed ? 1 : 0);
  103. xy[0] = x + 1;
  104. xy[1] = y + 1;                    
  105. xy[2] = x + w - 1;
  106. xy[3] = y + h - 1 - 1;
  107. vr_recfl(vdi_handle, xy);            /* Button background */
  108.     
  109. xy[8] = xy[2] = xy[0] = x;
  110. xy[9] = xy[7] = xy[1] = y + h - 1 - 1;
  111. xy[5] = xy[3] = y + 1;
  112. xy[6] = xy[4] = xy[0] + w - 1;
  113.                 
  114. vsl_color(vdi_handle, 1);
  115. v_pline(vdi_handle, 5, xy);    /* Draw a surrounding border */
  116.                 
  117. xy[0]++; xy[1]--;
  118. xy[2]++; xy[3]++;
  119. xy[4]--; xy[5]++;
  120. xy[6]--; xy[7]--;
  121. xy[8]++; xy[9]--;
  122.  
  123. if (pressed)
  124.     vsl_color(vdi_handle, 0);
  125.     
  126. v_pline(vdi_handle, 3, xy + 4);    /* 3d style border black */
  127. if (colours >= 16)
  128.     {
  129.     vsl_color(vdi_handle, pressed ? 1 : 0);
  130.     v_pline(vdi_handle, 3, xy);        /* 3D style border white */
  131.     }
  132.                     
  133. vsf_interior(vdi_handle, FIS_SOLID);
  134. vsf_color(vdi_handle, pressed ? 0 : 1);
  135.  
  136. xc = x + w / 2;
  137. yc = y + h / 2;                                        /* Calculate button center */
  138.                 
  139. switch(button)
  140.     {
  141.     case 0:                                                            /* Play button symbol */
  142.         {
  143.         xy[0] = xc - 3;
  144.         xy[1] = yc - 3;
  145.         xy[2] = xc + 3;
  146.         xy[3] = yc;
  147.         xy[4] = xc - 3;
  148.         xy[5] = yc + 3;
  149.         xy[6] = xy[0];
  150.         xy[7] = xy[1];
  151.         v_fillarea(vdi_handle, 4, xy);
  152.         break;
  153.         }
  154.                         
  155.     case 1:                                                        /* Stop button symbol */
  156.         {
  157.         xy[0] = xc - 3;
  158.         xy[1] = yc - 3;
  159.         xy[2] = xc + 3;
  160.         xy[3] = yc + 3;
  161.  
  162.         vr_recfl(vdi_handle, xy);
  163.         break;
  164.         }
  165.     }
  166. }                                            
  167.  
  168. /* 
  169.    Redraw object area
  170.    
  171.    oinf            -> Pointer to object info structure.
  172.    rx, ry        -> Upper left corner of redraw area.
  173.    rw, rh        -> Size of redraw area.
  174. */
  175. void cdecl redraw_ovl(OBJ_INFO *oinf, int rx, int ry, int rw, int rh)
  176. {
  177. int wr_x, wr_y, wr_w, wr_h, obj_xy[4], o;
  178. int clip_xy[4], xy[10];
  179.  
  180. vswr_mode(vdi_handle, MD_REPLACE);
  181.  
  182. if (rc_intersect(rx, ry, rw, rh, 
  183.                                  oinf->scr_x, oinf->scr_y, 
  184.                                  oinf->scr_w, oinf->scr_h, 
  185.                                  obj_xy))                                        /* Redraw necessary ? */
  186.   {
  187.     wind_get(oinf->window_handle, WF_FIRSTXYWH, &wr_x, &wr_y, &wr_w, &wr_h);
  188.     while (wr_w && wr_h)    /* Do it for each rectangle */
  189.       {
  190.       if (rc_intersect(obj_xy[0], obj_xy[1], obj_xy[2], obj_xy[3], 
  191.                                        wr_x, wr_y, wr_w, wr_h, clip_xy))    /* Object in rectangle ? */
  192.         {
  193.              clip_xy[2] += clip_xy[0] - 1;
  194.           clip_xy[3] += clip_xy[1] - 1;
  195.  
  196.         vs_clip(vdi_handle, 1, clip_xy);    /* Set clipping */
  197.         
  198.             vsf_interior(vdi_handle, FIS_SOLID);
  199.             if (colours >= 16)
  200.                 vsf_color(vdi_handle, 8);
  201.             else
  202.                 vsf_color(vdi_handle, 0);
  203.         vr_recfl(vdi_handle, clip_xy);        /* Fill area */
  204.         
  205.             vswr_mode(vdi_handle, MD_TRANS);    
  206.         v_gtext(vdi_handle, oinf->obj_x + 2, 
  207.                         oinf->obj_y + (oinf->obj_h - tx_height) / 2, 
  208.                         ((X32_INFO *)oinf->user)->name);
  209.             vswr_mode(vdi_handle, MD_REPLACE);
  210.  
  211.             xy[8] = xy[2] = xy[0] = oinf->obj_x;
  212.             xy[9] = xy[7] = xy[1] = oinf->obj_y + oinf->obj_h - 1;
  213.             xy[5] = xy[3] = oinf->obj_y;
  214.             xy[6] = xy[4] = oinf->obj_x + oinf->obj_w - 1;
  215.             if (colours >= 16)                                    /* Use 3D style */
  216.                 {
  217.                 vsl_color(vdi_handle, 1);
  218.                 v_pline(vdi_handle, 3, xy);
  219.                 vsl_color(vdi_handle, 0);
  220.                 v_pline(vdi_handle, 3, xy + 4);
  221.                 }
  222.             else                                                                /* Simple border */
  223.                 {
  224.                 vsl_color(vdi_handle, 1);
  225.                 v_pline(vdi_handle, 5, xy);
  226.                 }
  227.                         
  228.             for (o = 0; o < 2; o++)
  229.                 {
  230.                 draw_button(oinf->obj_x + oinf->obj_w - (o + 1) * (oinf->obj_h - 2) - 2,
  231.                                         oinf->obj_y, 
  232.                                         oinf->obj_h, oinf->obj_h,
  233.                                         o,
  234.                                         ((X32_INFO *)oinf->user)->button_pressed == o);
  235.                 }
  236.                                 
  237.         vs_clip(vdi_handle, 0, clip_xy);        /* Clipping off */
  238.         }
  239.  
  240.       wind_get(oinf->window_handle, WF_NEXTXYWH, &wr_x, &wr_y, &wr_w, &wr_h);
  241.       }
  242.     }
  243. }
  244.  
  245. /* 
  246.   This function will be called on left mouse click in object area.
  247.  
  248.     It checks, if one of the two buttons play/stop is selected.
  249.     If so, it    sets the button state to selected, does the corresponding
  250.     action, wait for releasing the mouse button, deselect the button
  251.     and returns.
  252. */
  253. void cdecl onclick_ovl(OBJ_INFO *oinf, int clicks, int mx, int my)
  254. {
  255. int bx, by;
  256. int o, m_button, d;
  257.  
  258. for (o = 0; o < 2; o++)
  259.     {
  260.     bx = oinf->obj_x + oinf->obj_w - (o + 1) * (oinf->obj_h - 2) - 2;
  261.     by = oinf->obj_y;
  262.     
  263.     if (mx >= bx && mx < bx + oinf->obj_h &&
  264.             my >= by && my < by + oinf->obj_h)        /* Is it the button ? */
  265.         {
  266.         graf_mouse(M_OFF, 0L);
  267.         
  268.         ((X32_INFO *)oinf->user)->button_pressed = o;        /* Select button */
  269.         redraw_ovl(oinf, bx, by, oinf->obj_h, oinf->obj_h);
  270.         
  271.         switch(o)
  272.             {
  273.             case 0:
  274.                 start_sound(oinf);
  275.                 break;
  276.                 
  277.             case 1:
  278.                 stop_sound(oinf);
  279.                 break;
  280.             }
  281.     
  282.         /* Wait for mouse release */
  283.         do
  284.             {
  285.             evnt_multi(MU_TIMER, 0, 0, 0,
  286.                                  0, 0, 0, 0, 0,
  287.                                  0, 0, 0, 0, 0,
  288.                                  NULL, 30, 0,
  289.                                  &d, &d, &m_button,
  290.                                  &d, &d, &d);
  291.                                                       
  292.             }while(m_button & 1);
  293.             
  294.         /* Deselect button */
  295.         ((X32_INFO *)oinf->user)->button_pressed = -1;
  296.         redraw_ovl(oinf, bx, by, oinf->obj_h - 2, oinf->obj_h);
  297.         graf_mouse(M_ON, 0L);
  298.         break;
  299.         }
  300.     }
  301. }
  302.